package com.stylefeng.guns.rest.modular.App.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.cache.CacheKit;
import com.stylefeng.guns.core.model.CommonKeyValue;
import com.stylefeng.guns.core.model.Pager;
import com.stylefeng.guns.rest.common.persistence.model.DriverInf;
import com.stylefeng.guns.rest.modular.App.dao.OrderInfMapper;
import com.stylefeng.guns.rest.modular.App.model.OrderCustomerRelation;
import com.stylefeng.guns.rest.modular.App.model.OrderInf;
import com.stylefeng.guns.rest.modular.App.model.TaskInf;
import com.stylefeng.guns.rest.modular.App.model.TaskOrder;
import com.stylefeng.guns.rest.modular.App.service.IOrderCustomerRelationService;
import com.stylefeng.guns.rest.modular.App.service.IOrderInfService;
import com.stylefeng.guns.rest.modular.App.service.ITaskInfService;
import com.stylefeng.guns.rest.modular.App.service.ITaskOrderService;
import com.stylefeng.guns.rest.modular.auth.util.JwtTokenUtil;
import com.stylefeng.guns.rest.modular.auth.validator.IDriverInfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


/**

 * 订单信息表 Service 实现
 * @author 张亚林
 * @Date 2018-11-12 17:32
 */
@Service
public class OrderInfServiceImpl extends ServiceImpl<OrderInfMapper,OrderInf> implements IOrderInfService {

    @Resource
    private OrderInfMapper orderInfMapper;
    @Autowired
    private ITaskInfService taskInfService;
    @Autowired
    private ITaskOrderService taskOrderService;
    @Autowired
    private IDriverInfService driverInfService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private IOrderCustomerRelationService orderCustomerRelationService;

    private static  final String TRANSFERCACHE="CONSTANT";

    /**
     * 查询订单信息表列表
     * @param orderInf 订单信息表对象
     * @return
     */
    public List<OrderInf> selectListOrderInf(OrderInf orderInf,String token)throws Exception{
        return  this.orderInfMapper.selectListOrderInf(orderInf);
    }
    /**
	 * 我的订单
     * @param pager 分页对象
     * @return onAddr onPos
     */
    public  Map pageListOrderInf(Pager pager,String token) throws Exception{
        Page page=new Page(pager.getPageNumber(),pager.getPageSize());
        page.setRecords(orderInfMapper.selectCustomerListOrderInf(page,(OrderInf)pager.getObj()));
        List<OrderInf> list = page.getRecords();
        for(OrderInf en:list){
            switch(en.getOrderState()){
                case "0":
                    en.setOrderStateTxt("未付款");
                    break;
                case "1":
                    en.setOrderStateTxt("已取消");
                    break;
                case "2":
                    en.setOrderStateTxt("已取消退款中");
                    break;
                case "3":
                    en.setOrderStateTxt("已取消已退款");
                    break;
                case "4":
                    en.setOrderStateTxt("未使用");
                    break;
                case "5":
                    en.setOrderStateTxt("等待驾驶员");
                    break;
                case "6":
                    en.setOrderStateTxt("已服务");
                    break;
                case "7":
                    en.setOrderStateTxt("服务结束");
                    break;
                default:
                    en.setOrderStateTxt("");
            }
        }
        Map mapDate = new HashMap();
        mapDate.put("rows", list);
        mapDate.put("total", page.getTotal());
        mapDate.put("page", page.getCurrent());
        mapDate.put("pageCount", page.getPages());
        return mapDate;
    }


    /**
     * 通过主键id查询的订单信息表列表
     * @param id 主键id
     * @return
     */
    public  OrderInf findOrderInfById(String id,String token)throws Exception{
        return  this.orderInfMapper.findOrderInfById(id);
    }

    /**
     * 新增订单信息表数据
     * @param orderInf  订单信息表对象
     * @return
     */
    @Transactional
    public int insertOrderInf(OrderInf orderInf,String token) throws Exception {
        //判断订单必填项
        /*'olId': 'da4e232894454491be90de333d0f4fdb',
                'olName': '成都—大同',
                'oscId': '',
                'ostId': '1',
                'ostName': '快车',
                'otId': 'CJ',
                'otName': '城际',
                'basePrice': '1',
                'oiOriginPrice': '2',
                'oiDestPrice': '3',
                'oiDistance': '4',
                'datePrice': '5',
                'distancePrice': '6',
                'ciTotalPrice': '10',
                'timePrice': '0',
                'ciId': '90001',
                'ciName': '韩洒',
                'ciNum': '1',
                'ciSendTime': '2018-12-26 23:59:00',
                'ciTel': '15391355103',
                'oiContainInvoice': '0',
                'oiStartAddress': '昆明市五华区城市心景1506',
                'oiStartPoint': '102.235643,25.235696',
                'oiEndAddress': '陕西西安北关十字',
                'oiEndPoint': '102.335643,29.235696',
                'note': '大型犬 必须9点钟赶到',
                'oiOrderTimeStart': '2018-12-26 23:59:00',
                'oiOrderTimeEnd': '2018-12-27 00:23:00',
                'payState': '1',
                'exSendTime': '2018-12-26 18:00:00',
                'exArrTime': '2018-12-26 20:00:00',
                'exFlightLeg': '泰国-昆明',
                'exOtherNo': '1234566',
                'exTicketNo': '95378639355',
                'vptCode': '02'*/

        return 0;
    }

    @Override
    public OrderInf getById(String oiId) throws Exception {
        OrderInf orderInf=new OrderInf();
        orderInf.setOiId(oiId);
       List<OrderInf> list= orderInfMapper.selectCustomerListOrderInf(orderInf);
       if(list!=null && list.size()>0){
           OrderInf en=list.get(0);
           switch(en.getOrderState()){
               case "0":
                   en.setOrderStateTxt("未付款");
                   break;
               case "1":
                   en.setOrderStateTxt("已取消");
                   break;
               case "2":
                   en.setOrderStateTxt("已取消退款中");
                   break;
               case "3":
                   en.setOrderStateTxt("已取已退款");
                   break;
               case "4":
                   en.setOrderStateTxt("未使用");
                   break;
               case "5":
                   en.setOrderStateTxt("等待驾驶员");
                   break;
               case "6":
                   en.setOrderStateTxt("已服务");
                   break;
               case "7":
                   en.setOrderStateTxt("服务结束");
                   break;
               default:
                   en.setOrderStateTxt("");
           }
           //
           OrderCustomerRelation orderCustomerRelation=new OrderCustomerRelation();
           orderCustomerRelation.setOiId(en.getOiId());
           en.setListCustomer(orderCustomerRelationService.selectListOrderCustomerRelation(orderCustomerRelation,null));
           /*System.out.println(JSON.toJSON(en).toString());*/
           return en;
       }
        return null;
    }

    /**
     * 更新订单信息表数据
     * @param orderInf 订单信息表对象
     * @return
     */
    @Transactional
    public int updateOrderInf(OrderInf orderInf,String token) throws Exception {
        return  this.orderInfMapper.updateOrderInf(orderInf);
    }

    @Override
    public OrderInf findOrderInfForUpdate(String id) throws Exception {

        return this.orderInfMapper.findOrderInfForUpdate(id);
    }

    @Override
    public OrderInf findOrderInfByQrcodeForUpdate(String qrcode) throws Exception {

        return  this.orderInfMapper.findOrderInfByQrcodeForUpdate(qrcode);
    }

    /**
     * 扫码上车
     * @param tiId 任务单Id
     * @param oiId
     * @param qrcode
     * @param token
     * @return
     * @throws Exception
     */
    @Transactional
    public int updateOrderInfUp(String tiId,String oiId,String qrcode,String  onAddr,String onPos,String token) throws Exception{
        if(((oiId==null || oiId.trim().length()<10) && (qrcode==null || qrcode.trim().length()<5)) || tiId==null || tiId.trim().length()<10 ){
            throw new RuntimeException("参数不全！");
        }

        if(onAddr==null || onAddr.trim().length()<3 || onPos==null || onPos.trim().length()<10){
            throw  new RuntimeException("上车经纬度和地址都不能为空！");
        }
        //检查任务包状态
        TaskInf taksInf=this.taskInfService.findTaskInfForUpdate(tiId);
        if(taksInf==null ){
            throw  new RuntimeException("任务包不存在！");
        }
        if(taksInf.getTiState().equals("0") || taksInf.getTiState().equals("2")){
            throw  new RuntimeException("任务包未指派或者已经完成！");
        }
        DriverInf driverInf=CacheKit.get(TRANSFERCACHE,jwtTokenUtil.getUsernameFromToken(token));
        String diId=driverInf.getDiId();
        if(!taksInf.getDiId().equals(diId)){
            throw  new RuntimeException("任务包已经指派他人！");
        }
        OrderInf orderInf=null;
        if(oiId!=null && oiId.length()>10){
            orderInf=this.findOrderInfForUpdate(oiId);
        }else{
            orderInf=this.findOrderInfByQrcodeForUpdate(qrcode);
        }
        if(orderInf==null ){
            throw  new RuntimeException("订单不存在！");
        }
        if(!orderInf.getCiState().equals("0")){
            throw  new RuntimeException("乘客不是未上车状态，不能操作！");
        }
        TaskOrder taskOrder=new TaskOrder();
        taskOrder.setTiId(tiId);
        taskOrder.setOiId(orderInf.getOiId());
        List list=taskOrderService.selectListTaskOrder(taskOrder,token);
        if(list==null || list.size()==0){
            throw  new RuntimeException("此任务单不在本次任务中！");
        }
        //乘客上车
        Date curDate=new Date();
        orderInf.setCiGetOnTime(curDate);
        orderInf.setCiGetOnPos(onPos);
        orderInf.setCiGetOnAddr(onAddr);
        this.orderInfMapper.updateOrderInfUp(orderInf);

        //如果第一个乘客扫码上车  记录任务开始执行时间、坐标和地址
        if(taksInf.getTiStartTime()==null){
            TaskInf updateTaksInf=new TaskInf();
            updateTaksInf.setTiId(tiId);
            updateTaksInf.setUpdateTime(curDate);
            updateTaksInf.setTiStartTime(curDate);
            updateTaksInf.setTiStartPoint(onPos);
            updateTaksInf.setCtStartAddress(onAddr);
            this.taskInfService.updateTaskInf(updateTaksInf,token);
        }
        return 0;
    }

    /**
     * 扫码下车
     * @param tiId 任务单Id
     * @param oiId
     * @param token
     * @return
     * @throws Exception
     */
    @Transactional
    public int updateOrderInfDown(String tiId,String oiId,String  offAddr,String offPos,String token) throws Exception{
        if(oiId==null || oiId.trim().length()<10 || tiId==null || tiId.trim().length()<10){
            throw new RuntimeException("参数不全！");
        }
        if(offAddr==null || offAddr.trim().length()<3 || offPos==null || offPos.trim().length()<10){
            throw  new RuntimeException("上车经纬度和地址都不能为空！");
        }
        TaskInf taksInf=this.taskInfService.findTaskInfForUpdate(tiId);
        if(taksInf==null ){
            throw  new RuntimeException("任务包不存在！");
        }
        if(taksInf.getTiState().equals("0") || taksInf.getTiState().equals("2")){
            throw  new RuntimeException("任务包未指派或者已经完成！");
        }
        DriverInf driverInf=CacheKit.get(TRANSFERCACHE,jwtTokenUtil.getUsernameFromToken(token));
        String diId=driverInf.getDiId();
        if(!taksInf.getDiId().equals(diId)){
            throw  new RuntimeException("任务包已经指派他人！");
        }
        OrderInf orderInf=this.findOrderInfForUpdate(oiId);
        if(orderInf==null ){
            throw  new RuntimeException("订单不存在！");
        }
        if(!orderInf.getCiState().equals("1")){
            throw  new RuntimeException("乘客未上车不能操作！");
        }
        //乘客下车
        Date curDate=new Date();
        TaskOrder taskOrder=new TaskOrder();
        taskOrder.setTiId(tiId);
        taskOrder.setOiId(oiId);
        List list=taskOrderService.selectListTaskOrder(taskOrder,token);
        if(list==null || list.size()==0){
            throw  new RuntimeException("此任务单不在本次任务中！");
        }
        //更新订单状态为已下车 记录下车时间、坐标和地址
        orderInf.setCiGetOffTime(curDate);
        orderInf.setCiGetOffPos(offPos);
        orderInf.setCiGetOffAddr(offAddr);
        this.orderInfMapper.updateOrderInfDown(orderInf);


        //查询所有乘客已经下车  将任务包修改成已经完成  并且记录完成经纬度和时间
        taskOrder=new TaskOrder();
        taskOrder.setTiId(tiId);
        List<TaskOrder> listTaskOrder=taskOrderService.selectListTaskOrder(taskOrder,token);
        for(TaskOrder en:listTaskOrder){
            orderInf= this.findOrderInfForUpdate(en.getOiId());
            if(!orderInf.getCiState().equals("3")){
                return 0;
            }
        }
        TaskInf updateTaksInf=new TaskInf();
        updateTaksInf.setTiId(tiId);
        updateTaksInf.setUpdateTime(curDate);
        updateTaksInf.setTiEndTime(curDate);
        updateTaksInf.setTiEndPoint(offPos);
        updateTaksInf.setCtEndAddress(offAddr);
        updateTaksInf.setTiState("2");
        this.taskInfService.updateTaskInf(updateTaksInf,token);
        //减少原驾驶员任务数
        DriverInf updateDriverInf=new  DriverInf();
        updateDriverInf.setDiId(driverInf.getDiId());
        updateDriverInf.setDiTaskNum(-1);
        driverInfService.updateDriverInfTaskNum(updateDriverInf,token);
        return 0;
    }


    @Override
    public int updateOrderInfRegainUp(OrderInf orderInf, String token) throws Exception {
        return 0;
    }



    @Override
    public int updateOrderInfRegainDown(OrderInf orderInf, String token) throws Exception {
        return 0;
    }

    @Override
    public int updateOrderInfUp(OrderInf orderInf, String token) throws Exception {
        this.orderInfMapper.updateOrderInfUp(orderInf);
        return 0;
    }

    @Override
    public int updateOrderInfDown(OrderInf orderInf, String token) throws Exception {
        this.orderInfMapper.updateOrderInfDown(orderInf);
        return 0;
    }

    /**
     * 查询订单信息表返回key-Value属性
     * @param orderInf 系统操作对象
     * @return
     */
    public List<CommonKeyValue> optionsOrderInf(OrderInf orderInf,String token) throws Exception {
        List<OrderInf> listOrderInf=this.orderInfMapper.selectListOrderInf(orderInf);
        List<CommonKeyValue> listOptions=new ArrayList<CommonKeyValue>();
        for(OrderInf item:listOrderInf){
            CommonKeyValue opts=new CommonKeyValue();
            opts.setId(""+item.getOiId());
            opts.setValue(item.getOiCode());
            listOptions.add(opts);
        }
        return listOptions;
    }
}
